package com.yupi.yupicturebackend.manager.upload;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.CIObject;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import com.qcloud.cos.model.ciModel.persistence.ProcessResults;
import com.yupi.yupicturebackend.Exception.BusinessException;
import com.yupi.yupicturebackend.Exception.ErrorCode;
import com.yupi.yupicturebackend.config.CosClientConfig;
import com.yupi.yupicturebackend.manager.CosManager;
import com.yupi.yupicturebackend.model.dto.UploadPictureResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 图片上传模版
 */
@Component
@Slf4j
public abstract class PictureUploadTemplate {

    @Resource
    private CosClientConfig cosClientConfig;
    @Resource
    private CosManager cosManager;


    /**
     * 通用图片上传
     */
    public UploadPictureResult uploadPictureResult(Object inputSource, String prefix) {
        //  1.校验文件合法性
        isPictureValid(inputSource);
        // 2. 拼接文件上传url
        String UUID = RandomUtil.randomString(8);
        String filename = getOriginalFilename(inputSource);

        String upload_Name = String.format("%s_%s.%S", DateUtil.now(), UUID, FileUtil.getSuffix(filename));
        String upload_Path = String.format("%s/%s", prefix, upload_Name);
        // 3.解析文件属性，封装对象返回给调用者

        File file = null;
        try {
            // 1.创建临时文件
            file = File.createTempFile(upload_Path, null);
            // 2.填充临时文件
            processFile(inputSource,file);
            // 3.将临时文件上传到cos
            PutObjectResult putObjectResult = cosManager.putPictureObject(upload_Path, file);
            // 4.获取图片对象
            ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();

            ProcessResults processResults = putObjectResult.getCiUploadResult().getProcessResults();

            List<CIObject> objectList = processResults.getObjectList();
            if (CollUtil.isNotEmpty(objectList)) {
                CIObject ciObject = objectList.get(0);
                CIObject thumbnailObject = objectList.get(1);
                return buildResultNew(filename, ciObject, thumbnailObject,imageInfo);
            }
            return buildResult(imageInfo, upload_Path, upload_Name, file);
        } catch (Exception e) {
            log.error("图片上传到存储对象失败！path={}, name={}", upload_Path, upload_Name, e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传文件失败");
        } finally {
            //5. 删除临时文件
            deleteTemplateFile(file);
        }

    }

    private UploadPictureResult buildResultNew(String fileName, CIObject ciObject, CIObject thumbnailObject,ImageInfo imageInfo) {
        String format = ciObject.getFormat();
        int width = ciObject.getWidth();
        int height = ciObject.getHeight();
        double scale = NumberUtil.round(height * 1.0 / width, 2).doubleValue();

        // 封装返回结果
        UploadPictureResult uploadPictureResult = new UploadPictureResult();
        uploadPictureResult.setPicName(FileUtil.mainName(fileName));
        uploadPictureResult.setPicSize(Long.valueOf(ciObject.getSize()));
        uploadPictureResult.setPicWidth(width);
        uploadPictureResult.setPicHeight(height);
        uploadPictureResult.setPicScale(scale);
        uploadPictureResult.setPicFormat(format);
        uploadPictureResult.setThumbnailUrl(cosClientConfig.getHost() + '/' + thumbnailObject.getKey());
        // 设置压缩后的地址
        uploadPictureResult.setUrl(cosClientConfig.getHost() + '/' + ciObject.getKey());
        uploadPictureResult.setPicColor(imageInfo.getAve());
        // 返回文件对象
        return uploadPictureResult;
    }

    /**
     * 封装返回结果
     * @param imageInfo
     * @param upload_Path
     * @param upload_Name
     * @param file
     * @return
     */
    private UploadPictureResult buildResult(ImageInfo imageInfo, String upload_Path, String upload_Name, File file) {
        String format = imageInfo.getFormat();
        int width = imageInfo.getWidth();
        int height = imageInfo.getHeight();
        double scale = NumberUtil.round(height * 1.0 / width, 2).doubleValue();

        // 封装返回结果
        UploadPictureResult uploadPictureResult = new UploadPictureResult();
        uploadPictureResult.setUrl(cosClientConfig.getHost() + '/' + upload_Path);
        uploadPictureResult.setPicName(upload_Name);
        uploadPictureResult.setPicSize(FileUtil.size(file));
        uploadPictureResult.setPicWidth(width);
        uploadPictureResult.setPicHeight(height);
        uploadPictureResult.setPicScale(scale);
        uploadPictureResult.setPicFormat(format);
        uploadPictureResult.setPicColor(imageInfo.getAve());
        // 返回文件对象
        return uploadPictureResult;
    }

    public void deleteTemplateFile(File file) {
        if (file != null) {
            boolean success = file.delete();
            if (!success) {
                // 没有删除成功
                log.error("delete temp file fail,filepath = {}", file.getAbsolutePath());
            }
        }
    }


    /**
     * 判断是否合法
     * @param inputSource
     */
    protected abstract void isPictureValid(Object inputSource);
    /**
     * 填充文件
     * @param inputSource
     * @param file
     */
    protected abstract void processFile(Object inputSource, File file) throws IOException;
    /**
     * 获取原始文件名
     * @param inputSource
     * @return
     */
    protected abstract String getOriginalFilename(Object inputSource);



    // todo 处理路径方法
    final List<String> MUST_SUFFIX = Arrays.asList("jpeg", "jpg", "png", "webp", "gif", "bmp", "tiff", "svg");
    public String processUploadPath(String uploadPath) {
        // 统一转为小写处理（保证后缀大小写不敏感）
        String lowerPath = uploadPath.toLowerCase();
        // 遍历所有合法后缀，检查是否以.后缀结尾
        for (String suffix : MUST_SUFFIX) {
            // 支持带参数链接（如image.png?width=200）
            if (lowerPath.matches(".*\\." + suffix + "($|\\?.*)")) {
                return uploadPath;
            }
        }
        return uploadPath + ".png"; // 默认补全为 PNG（兼容性最佳）
    }







}



